/******************************************************************************

  Sega encryption emulation                                 by Nicola Salmoria


  Several Sega Z80 games have program ROMs encrypted using a common algorithm
  (but with a different key).
  The hardware used to implement this encryption is either a custom CPU, or an
  epoxy block which probably contains a standard Z80 + PALs.

  You can think of the decryption algorithm as a black box which takes as
  input D3, D5, D7, M1, A0, A4, A8 and A12, and returns the decrypted D3, D5
  and D7. [Dn are the data lines, An the address lines, M1 is the Z80 pin which
  tells whether the CPU is accessing data or opcodes]. D0, D1, D3, D4 and D6
  are always unaffected.

  We can summarize that using a XOR mask laid out like this:

    0 1 2 3 4 5 6 7 8 9 a b c d e f
  0 A A A A A A A A B B B B B B B B
  1 A A A A A A A A B B B B B B B B
  2 C C C C C C C C D D D D D D D D
  3 C C C C C C C C D D D D D D D D
  4 A A A A A A A A B B B B B B B B
  5 A A A A A A A A B B B B B B B B
  6 C C C C C C C C D D D D D D D D
  7 C C C C C C C C D D D D D D D D
  8 D D D D D D D D C C C C C C C C
  9 D D D D D D D D C C C C C C C C
  a B B B B B B B B A A A A A A A A
  b B B B B B B B B A A A A A A A A
  c D D D D D D D D C C C C C C C C
  d D D D D D D D D C C C C C C C C
  e B B B B B B B B A A A A A A A A
  f B B B B B B B B A A A A A A A A

  on the left edge you have the most significant nibble of the data, on the top
  edge the least significant nibble. For example, if the input data is 0xc0, it
  will be XORed with D. As you can see, the table is symmetrical, so the 8
  possible combinations of D3, D5 and D7 only require 4 different XOR values.
  Since only D3, D5 and D7 are affected, A, B, C and D can have only these
  values: 0x00, 0x08, 0x20, 0x28, 0x80, 0x88, 0xa0, 0xa8.
  Another important thing to note is that A XOR B XOR C XOR D must always be 0;
  that is, it must cause a permutation. If that weren't the case, there would
  be values impossible to obtain.

  We need 32 of these tables, one for every possible combination of M1, A0, A4,
  A8 and A12. However, all the games currently known are full of repetitions
  and only use 6 different tables, the only exceptions being Pengo and Yamato
  which have 7 (but one of them is { 0x00, 0x00, 0x00, 0x00 } ). This is most
  likely a limitation of the hardware.
  Some of the early games are even weaker: of the 6 different tables, they use
  3 for opcodes and 3 for data, and always coupled in the same way.

  In all games currently known, only bytes in the memory range 0x0000-0x7fff
  (A15 = 0) are encrypted. My guess is that this was done to allow games to
  copy code to RAM (in the memory range 0x8000-0xffff) and execute it from
  there without the CPU trying to decrypt it and messing everything up.
  However Zaxxon has RAM at 0x6000, and the CPU doesn't seem to interfere with
  it; but it doesn't execute code from there, so it's possible that the CPU is
  encrypting the data while writing it and decrypting it while reading (that
  would seem kind of strange though). Video and sprite RAM and memory mapped
  ports are all placed above 0x8000.

  Given its strict limitations, this encryption is reasonably easy to break,
  and very vulnerable to known plaintext attacks.



  Ninja Princess:

  there is a (bootleg?) board which has a standard Z80 + 2 bipolar PROMs
  instead of the custom CPU. The encryption table is different from the
  original Ninja Princess; it is actually the same as Flicky.

  The first PROM is 32x8 (?) and contains the number (0..5) of the table to
  use depending on M1, A0, A4, A8, A12:

  00: 11 00 33 22 00 44 44 00 11 33 33 22 44 44 44 22
  10: 11 55 55 33 44 22 55 22 11 33 55 33 44 44 11 22

  The second PROM is 256x4 and contains the 6 different XOR tables:

       A  D  B  C  C  B  D  A
  00: 09 09 0A 0A 0A 0A 09 09
  08: 0E 08 0B 0D 0D 0B 08 0E
  10: 0A 0C 0A 0C 0C 0A 0C 0A
  18: 0B 0E 0E 0B 0B 0E 0E 0B
  20: 0C 0C 0F 0F 0F 0F 0C 0C
  28: 08 0D 0B 0E 0E 0B 0D 08
  [the remaining bytes are all 0F]
  bit 3 is not used.
  bits 0-2 is the XOR code inverted (0 = 0xa8, 1 = 0xa0 ... 6 = 0x08 7 = 0x00)

  Here is a diagram showing how it works:

  data to                             XOR
  decode                             value
                      A ---
  D7  --------------- 0|   |
  D3  --------------- 1|   |
  D5  --------------- 2| P |D
          A --- D      | R |0 ---|>--- D3
  M1  --- 0| P |0 --- 3| O |1 ---|>--- D5
  A0  --- 1| R |1 --- 4| M |2 ---|>--- D7
  A4  --- 2| O |2 --- 5| 2 |3 ---
  A8  --- 3| M |3 --- 6|   |
  A12 --- 4| 1 |4 --- 7|   |
            ---         ---


  My Hero:

  the bootleg does the decryption using a single 256x4 PROM, mapped in the
  obvious way:

  data to            XOR
  decode            value
          A ---
  D3  --- 0|   |
  D5  --- 1|   |D
  D7  --- 2| P |0 --- D3
  A0  --- 3| R |1 --- D5
  A4  --- 4| O |2 --- D7
  A8  --- 5| M |3 ---
  A12 --- 6|   |
  M1  --- 7|   |
            ---



  List of encrypted games currently known:

 CPU Part #         Game                   Comments
  315-5010      Pengo                  unencrypted version available
  315-5013      Super Zaxxon           used Zaxxon for known plaintext attack
  ???-????      Super Locomotive
  ???-???? M120 Razzmatazz             same key as Ninja Princess
  315-5018      Yamato
  315-5028      Sindbad Mystery
  315-5033      Regulus
  315-5041 M140 Mister Viking
  315-5048      SWAT                   used Bull Fight for k.p.a.
  315-5051      Flicky &
                Ninja Princess (bootleg)
  ???-????      Water Match            not available yet
  315-5061      Future Spy
  315-5065      Bull Fight
  315-5069      Star Force             game by Tehkan; same key as Super Locomotive
  315-5093      Pitfall II
  315-5098      Ninja Princess         unencrypted version available
  315-5102      Sega Ninja             unencrypted version available
  315-5110      I'm Sorry              used My Hero for k.p.a.
  315-5114      ?? pcb 834-5492        not decoded yet
  315-5115      TeddyBoy Blues
  315-5135      Heavy Metal &
                Wonder Boy (set 1 & 2; bootlegs?)
  ???-????      My Hero


  The following games use a different encryption algorithm:

  315-5162 4D Warriors            used I'm Sorry for k.p.a.
  315-5177 Wonder Boy (set 3)     not decoded yet
  315-5178 Wonder Boy (set 4)     used Wonder Boy Deluxe for k.p.a.
  ???-???? Gardia                 not decoded yet


  The following games use another different encryption algorithm, much more
  secure than the previous two, which has not been broken yet. It might be
  similar to the one used in System 16 games.

  317-5014?DakkoChan Jansoh
  317-0029 Block Gal              NEC MC8123B 651 packaged like System16's 68000
  317-0030 Perfect Billiards
  317-0043 Wonder Boy Monster Land
  317-0054 Shinobi (sound CPU)    NEC MC8123B 651
  317-0064 Ufo Senshi Yohko Chan



  Some text found in the ROMs:

  Super Locomotive SEGA FUKUMURA MIZUNAGA
  Yamato           SECULITY BY M,MIZUNAGA
  Regulus          SECULITY BY SYUICHI,KATAGI
  Mister Viking    SECURITY BY S.KATAGI  CONTROL CHIP M140
  SWAT             SECURITY BY S.KATAGI
  Flicky           SECURITY BY S.KATAGI
  Star Force       STAR FORCE TEHKAN. SECURITY BY SEGA ENTERPRISESE

******************************************************************************/

#include "driver.h"

static void sega_decode(const unsigned char xortable[32][4])
{
	int A;
	unsigned char *rom = memory_region(REGION_CPU1);
	int diff = memory_region_length(REGION_CPU1) / 2;


	memory_set_opcode_base(0,rom+diff);

	for (A = 0x0000;A < 0x8000;A++)
	{
		int row,col;
		unsigned char src;


		src = rom[A];

		/* pick the translation table from bits 0, 4, 8 and 12 of the address */
		row = (A & 1) + (((A >> 4) & 1) << 1) + (((A >> 8) & 1) << 2) + (((A >> 12) & 1) << 3);

		/* pick the offset in the table from bits 3 and 5 of the source data */
		col = ((src >> 3) & 1) + (((src >> 5) & 1) << 1);
		/* the bottom half of the translation table is the mirror image of the top */
		if (src & 0x80) col = 3 - col;

		/* decode the opcodes */
		rom[A + diff] = src ^ xortable[2*row][col];

		/* decode the data */
		rom[A] = src ^ xortable[2*row+1][col];

		if (xortable[2*row][col] == 0xff)	/* table incomplete! (for development) */
			rom[A + diff] = 0x00;
		if (xortable[2*row+1][col] == 0xff)	/* table incomplete! (for development) */
			rom[A] = 0xee;
	}

	/* copy the opcodes from the not encrypted part of the ROMs */
	for (A = 0x8000;A < diff;A++)
		rom[A + diff] = rom[A];
}



void pengo_decode(void)
{
	static const unsigned char xortable[32][4] =
	{
		/*       opcode                   data                     address      */
		/*  A    B    C    D         A    B    C    D                           */
		{ 0xa0,0x88,0x88,0xa0 }, { 0x28,0xa0,0x28,0xa0 },	/* ...0...0...0...0 */
		{ 0x28,0xa0,0x28,0xa0 }, { 0xa0,0x88,0x88,0xa0 },	/* ...0...0...0...1 */
		{ 0xa0,0x88,0x00,0x28 }, { 0xa0,0x88,0x00,0x28 },	/* ...0...0...1...0 */
		{ 0x08,0x20,0xa8,0x80 }, { 0xa0,0x88,0x88,0xa0 },	/* ...0...0...1...1 */
		{ 0x08,0x08,0xa8,0xa8 }, { 0x28,0xa0,0x28,0xa0 },	/* ...0...1...0...0 */
		{ 0xa0,0x88,0x00,0x28 }, { 0x08,0x08,0xa8,0xa8 },	/* ...0...1...0...1 */
		{ 0xa0,0x88,0x00,0x28 }, { 0xa0,0x88,0x00,0x28 },	/* ...0...1...1...0 */
		{ 0xa0,0x88,0x00,0x28 }, { 0x00,0x00,0x00,0x00 },	/* ...0...1...1...1 */
		{ 0x88,0x88,0x28,0x28 }, { 0xa0,0x88,0x00,0x28 },	/* ...1...0...0...0 */
		{ 0x88,0x88,0x28,0x28 }, { 0x00,0x00,0x00,0x00 },	/* ...1...0...0...1 */
		{ 0x08,0x20,0xa8,0x80 }, { 0x08,0x20,0xa8,0x80 },	/* ...1...0...1...0 */
		{ 0xa0,0x88,0x88,0xa0 }, { 0xa0,0x88,0x00,0x28 },	/* ...1...0...1...1 */
		{ 0x08,0x08,0xa8,0xa8 }, { 0x88,0x88,0x28,0x28 },	/* ...1...1...0...0 */
		{ 0x00,0x00,0x00,0x00 }, { 0x88,0x88,0x28,0x28 },	/* ...1...1...0...1 */
		{ 0x08,0x20,0xa8,0x80 }, { 0x08,0x20,0xa8,0x80 },	/* ...1...1...1...0 */
		{ 0x08,0x08,0xa8,0xa8 }, { 0xa0,0x88,0x00,0x28 }	/* ...1...1...1...1 */
	};


	sega_decode(xortable);
}


void szaxxon_decode(void)
{
	static const unsigned char xortable[32][4] =
	{
		/*       opcode                   data                     address      */
		/*  A    B    C    D         A    B    C    D                           */
		{ 0x88,0xa0,0xa0,0x88 }, { 0x28,0x28,0x88,0x88 },	/* ...0...0...0...0 */
		{ 0x08,0x20,0xa8,0x80 }, { 0x88,0x88,0x28,0x28 },	/* ...0...0...0...1 */
		{ 0xa8,0x20,0x80,0x08 }, { 0x20,0xa8,0x20,0xa8 },	/* ...0...0...1...0 */
		{ 0x88,0xa0,0xa0,0x88 }, { 0x28,0x28,0x88,0x88 },	/* ...0...0...1...1 */
		{ 0x08,0x20,0xa8,0x80 }, { 0x88,0x88,0x28,0x28 },	/* ...0...1...0...0 */
		{ 0x88,0xa0,0xa0,0x88 }, { 0x28,0x28,0x88,0x88 },	/* ...0...1...0...1 */
		{ 0xa8,0x20,0x80,0x08 }, { 0x20,0xa8,0x20,0xa8 },	/* ...0...1...1...0 */
		{ 0x08,0x20,0xa8,0x80 }, { 0x88,0x88,0x28,0x28 },	/* ...0...1...1...1 */
		{ 0x08,0x20,0xa8,0x80 }, { 0x88,0x88,0x28,0x28 },	/* ...1...0...0...0 */
		{ 0x88,0xa0,0xa0,0x88 }, { 0x28,0x28,0x88,0x88 },	/* ...1...0...0...1 */
		{ 0x88,0xa0,0xa0,0x88 }, { 0x28,0x28,0x88,0x88 },	/* ...1...0...1...0 */
		{ 0xa8,0x20,0x80,0x08 }, { 0x20,0xa8,0x20,0xa8 },	/* ...1...0...1...1 */
		{ 0xa8,0x20,0x80,0x08 }, { 0x20,0xa8,0x20,0xa8 },	/* ...1...1...0...0 */
		{ 0xa8,0x20,0x80,0x08 }, { 0x20,0xa8,0x20,0xa8 },	/* ...1...1...0...1 */
		{ 0x08,0x20,0xa8,0x80 }, { 0x88,0x88,0x28,0x28 },	/* ...1...1...1...0 */
		{ 0x88,0xa0,0xa0,0x88 }, { 0x28,0x28,0x88,0x88 }	/* ...1...1...1...1 */
	};


	sega_decode(xortable);
}


void suprloco_decode(void)
{
	static const unsigned char xortable[32][4] =
	{
		/*       opcode                   data                     address      */
		/*  A    B    C    D         A    B    C    D                           */
		{ 0x20,0x08,0x80,0xa8 }, { 0xa8,0xa8,0xa8,0xa8 },	/* ...0...0...0...0 */
		{ 0x20,0x08,0x80,0xa8 }, { 0xa8,0xa8,0xa8,0xa8 },	/* ...0...0...0...1 */
		{ 0x20,0x08,0x80,0xa8 }, { 0xa8,0xa8,0xa8,0xa8 },	/* ...0...0...1...0 */
		{ 0x88,0x00,0xa0,0x28 }, { 0xa0,0x88,0x88,0xa0 },	/* ...0...0...1...1 */
		{ 0x88,0x00,0xa0,0x28 }, { 0xa0,0x88,0x88,0xa0 },	/* ...0...1...0...0 */
		{ 0x20,0x08,0x80,0xa8 }, { 0xa8,0xa8,0xa8,0xa8 },	/* ...0...1...0...1 */
		{ 0x88,0x00,0xa0,0x28 }, { 0xa0,0x88,0x88,0xa0 },	/* ...0...1...1...0 */
		{ 0x28,0xa0,0x28,0xa0 }, { 0x88,0x88,0x28,0x28 },	/* ...0...1...1...1 */
		{ 0x20,0x08,0x80,0xa8 }, { 0xa8,0xa8,0xa8,0xa8 },	/* ...1...0...0...0 */
		{ 0x88,0x00,0xa0,0x28 }, { 0xa0,0x88,0x88,0xa0 },	/* ...1...0...0...1 */
		{ 0x88,0x00,0xa0,0x28 }, { 0xa0,0x88,0x88,0xa0 },	/* ...1...0...1...0 */
		{ 0x20,0x08,0x80,0xa8 }, { 0xa8,0xa8,0xa8,0xa8 },	/* ...1...0...1...1 */
		{ 0x88,0x00,0xa0,0x28 }, { 0xa0,0x88,0x88,0xa0 },	/* ...1...1...0...0 */
		{ 0x28,0xa0,0x28,0xa0 }, { 0x88,0x88,0x28,0x28 },	/* ...1...1...0...1 */
		{ 0x20,0x08,0x80,0xa8 }, { 0xa8,0xa8,0xa8,0xa8 },	/* ...1...1...1...0 */
		{ 0x88,0x00,0xa0,0x28 }, { 0xa0,0x88,0x88,0xa0 }	/* ...1...1...1...1 */
	};


	sega_decode(xortable);
}


void yamato_decode(void)
{
	static const unsigned char xortable[32][4] =
	{
		/*       opcode                   data                     address      */
		/*  A    B    C    D         A    B    C    D                           */
		{ 0x88,0xa0,0x28,0x00 }, { 0x88,0xa0,0xa0,0x88 },	/* ...0...0...0...0 */
		{ 0x20,0xa8,0x08,0x80 }, { 0x88,0xa0,0xa0,0x88 },	/* ...0...0...0...1 */
		{ 0x88,0xa0,0xa0,0x88 }, { 0x88,0xa0,0xa0,0x88 },	/* ...0...0...1...0 */
		{ 0x88,0xa0,0xa0,0x88 }, { 0x20,0xa8,0x08,0x80 },	/* ...0...0...1...1 */
		{ 0x88,0xa0,0x28,0x00 }, { 0x88,0xa0,0x28,0x00 },	/* ...0...1...0...0 */
		{ 0x88,0xa0,0xa0,0x88 }, { 0x88,0xa0,0xa0,0x88 },	/* ...0...1...0...1 */
		{ 0x20,0xa8,0x08,0x80 }, { 0x20,0xa8,0x08,0x80 },	/* ...0...1...1...0 */
		{ 0x88,0xa0,0xa0,0x88 }, { 0x88,0xa0,0xa0,0x88 },	/* ...0...1...1...1 */
		{ 0x20,0xa8,0x08,0x80 }, { 0x88,0xa0,0x28,0x00 },	/* ...1...0...0...0 */
		{ 0x20,0xa8,0x08,0x80 }, { 0x28,0x28,0x88,0x88 },	/* ...1...0...0...1 */
		{ 0xa0,0x28,0xa0,0x28 }, { 0x20,0xa8,0x08,0x80 },	/* ...1...0...1...0 */
		{ 0x28,0x28,0x88,0x88 }, { 0x20,0xa8,0x08,0x80 },	/* ...1...0...1...1 */
		{ 0x20,0xa8,0x08,0x80 }, { 0x88,0xa0,0x28,0x00 },	/* ...1...1...0...0 */
		{ 0x88,0xa0,0x28,0x00 }, { 0x88,0xa0,0x28,0x00 },	/* ...1...1...0...1 */
		{ 0xa0,0x28,0xa0,0x28 }, { 0x88,0x00,0xa0,0x28 },	/* ...1...1...1...0 */
		{ 0x20,0xa8,0x08,0x80 }, { 0x00,0x00,0x00,0x00 }	/* ...1...1...1...1 */
	};


	sega_decode(xortable);
}


void sindbadm_decode(void)
{
	static const unsigned char xortable[32][4] =
	{
		/*       opcode                   data                     address      */
		/*  A    B    C    D         A    B    C    D                           */
		{ 0x28,0xa0,0x28,0xa0 }, { 0x88,0x88,0x28,0x28 },	/* ...0...0...0...0 */
		{ 0xa8,0xa8,0xa8,0xa8 }, { 0x00,0x28,0xa0,0x88 },	/* ...0...0...0...1 */
		{ 0xa8,0xa8,0xa8,0xa8 }, { 0x00,0x28,0xa0,0x88 },	/* ...0...0...1...0 */
		{ 0x28,0xa0,0x28,0xa0 }, { 0x88,0x88,0x28,0x28 },	/* ...0...0...1...1 */
		{ 0xa8,0x80,0x80,0xa8 }, { 0xa0,0x28,0x88,0x00 },	/* ...0...1...0...0 */
		{ 0x28,0xa0,0x28,0xa0 }, { 0x88,0x88,0x28,0x28 },	/* ...0...1...0...1 */
		{ 0xa8,0xa8,0xa8,0xa8 }, { 0x00,0x28,0xa0,0x88 },	/* ...0...1...1...0 */
		{ 0xa8,0xa8,0xa8,0xa8 }, { 0x00,0x28,0xa0,0x88 },	/* ...0...1...1...1 */
		{ 0x28,0xa0,0x28,0xa0 }, { 0x88,0x88,0x28,0x28 },	/* ...1...0...0...0 */
		{ 0x28,0xa0,0x28,0xa0 }, { 0x88,0x88,0x28,0x28 },	/* ...1...0...0...1 */
		{ 0xa8,0xa8,0xa8,0xa8 }, { 0x00,0x28,0xa0,0x88 },	/* ...1...0...1...0 */
		{ 0xa8,0xa8,0xa8,0xa8 }, { 0x00,0x28,0xa0,0x88 },	/* ...1...0...1...1 */
		{ 0x28,0xa0,0x28,0xa0 }, { 0x88,0x88,0x28,0x28 },	/* ...1...1...0...0 */
		{ 0xa8,0x80,0x80,0xa8 }, { 0xa0,0x28,0x88,0x00 },	/* ...1...1...0...1 */
		{ 0x28,0xa0,0x28,0xa0 }, { 0x88,0x88,0x28,0x28 },	/* ...1...1...1...0 */
		{ 0x28,0xa0,0x28,0xa0 }, { 0x88,0x88,0x28,0x28 }	/* ...1...1...1...1 */
	};


	sega_decode(xortable);
}


void regulus_decode(void)
{
	static const unsigned char xortable[32][4] =
	{
		/*       opcode                   data                     address      */
		/*  A    B    C    D         A    B    C    D                           */
		{ 0x28,0x00,0x88,0xa0 }, { 0x88,0x88,0x28,0x28 },	/* ...0...0...0...0 */
		{ 0x28,0x00,0x88,0xa0 }, { 0x28,0xa0,0x28,0xa0 },	/* ...0...0...0...1 */
		{ 0x88,0x88,0x28,0x28 }, { 0x88,0x00,0xa0,0x28 },	/* ...0...0...1...0 */
		{ 0x88,0x00,0xa0,0x28 }, { 0x28,0xa0,0x28,0xa0 },	/* ...0...0...1...1 */
		{ 0x28,0x00,0x88,0xa0 }, { 0x88,0x88,0x28,0x28 },	/* ...0...1...0...0 */
		{ 0x88,0x88,0x28,0x28 }, { 0x88,0x88,0x28,0x28 },	/* ...0...1...0...1 */
		{ 0x88,0x00,0xa0,0x28 }, { 0x88,0x00,0xa0,0x28 },	/* ...0...1...1...0 */
		{ 0xa0,0x88,0x88,0xa0 }, { 0xa0,0x88,0x88,0xa0 },	/* ...0...1...1...1 */
		{ 0x80,0xa8,0x20,0x08 }, { 0x28,0x00,0x88,0xa0 },	/* ...1...0...0...0 */
		{ 0x28,0xa0,0x28,0xa0 }, { 0x28,0x00,0x88,0xa0 },	/* ...1...0...0...1 */
		{ 0x80,0xa8,0x20,0x08 }, { 0x80,0xa8,0x20,0x08 },	/* ...1...0...1...0 */
		{ 0x28,0xa0,0x28,0xa0 }, { 0x80,0xa8,0x20,0x08 },	/* ...1...0...1...1 */
		{ 0xa0,0x88,0x88,0xa0 }, { 0x28,0x00,0x88,0xa0 },	/* ...1...1...0...0 */
		{ 0x80,0xa8,0x20,0x08 }, { 0xa0,0x88,0x88,0xa0 },	/* ...1...1...0...1 */
		{ 0xa0,0x88,0x88,0xa0 }, { 0x80,0xa8,0x20,0x08 },	/* ...1...1...1...0 */
		{ 0xa0,0x88,0x88,0xa0 }, { 0xa0,0x88,0x88,0xa0 }	/* ...1...1...1...1 */
	};


	sega_decode(xortable);
}


void mrviking_decode(void)
{
	static const unsigned char xortable[32][4] =
	{
		/*       opcode                   data                     address      */
		/*  A    B    C    D         A    B    C    D                           */
		{ 0x28,0xa0,0x28,0xa0 }, { 0x88,0x88,0x28,0x28 },	/* ...0...0...0...0 */
		{ 0x88,0x00,0xa0,0x28 }, { 0x88,0x88,0x28,0x28 },	/* ...0...0...0...1 */
		{ 0x28,0x00,0x88,0xa0 }, { 0x28,0xa0,0x28,0xa0 },	/* ...0...0...1...0 */
		{ 0x88,0x00,0xa0,0x28 }, { 0x88,0x00,0xa0,0x28 },	/* ...0...0...1...1 */
		{ 0x28,0x00,0x88,0xa0 }, { 0x88,0x88,0x28,0x28 },	/* ...0...1...0...0 */
		{ 0x88,0x88,0x28,0x28 }, { 0x28,0xa0,0x28,0xa0 },	/* ...0...1...0...1 */
		{ 0xa0,0x88,0x88,0xa0 }, { 0x28,0x00,0x88,0xa0 },	/* ...0...1...1...0 */
		{ 0xa0,0x88,0x88,0xa0 }, { 0xa0,0x88,0x88,0xa0 },	/* ...0...1...1...1 */
		{ 0x88,0x88,0x28,0x28 }, { 0x88,0x88,0x28,0x28 },	/* ...1...0...0...0 */
		{ 0x88,0x00,0xa0,0x28 }, { 0x88,0x88,0x28,0x28 },	/* ...1...0...0...1 */
		{ 0xa0,0x88,0x00,0x28 }, { 0x28,0x00,0x88,0xa0 },	/* ...1...0...1...0 */
		{ 0xa0,0x88,0x00,0x28 }, { 0x88,0x00,0xa0,0x28 },	/* ...1...0...1...1 */
		{ 0x28,0x00,0x88,0xa0 }, { 0xa0,0x88,0x00,0x28 },	/* ...1...1...0...0 */
		{ 0xa0,0x88,0x00,0x28 }, { 0xa0,0x88,0x00,0x28 },	/* ...1...1...0...1 */
		{ 0xa0,0x88,0x88,0xa0 }, { 0x28,0x00,0x88,0xa0 },	/* ...1...1...1...0 */
		{ 0xa0,0x88,0x00,0x28 }, { 0xa0,0x88,0x88,0xa0 }	/* ...1...1...1...1 */
	};


	sega_decode(xortable);
}


void swat_decode(void)
{
	static const unsigned char xortable[32][4] =
	{
		/*       opcode                   data                     address      */
		/*  A    B    C    D         A    B    C    D                           */
		{ 0x88,0x00,0xa0,0x28 }, { 0xa0,0xa0,0xa0,0xa0 },	/* ...0...0...0...0 */
		{ 0x88,0x00,0xa0,0x28 }, { 0x88,0xa0,0xa0,0x88 },	/* ...0...0...0...1 */
		{ 0xa0,0x88,0x00,0x28 }, { 0x88,0x00,0xa0,0x28 },	/* ...0...0...1...0 */
		{ 0xa0,0xa0,0xa0,0xa0 }, { 0x88,0x00,0xa0,0x28 },	/* ...0...0...1...1 */
		{ 0x28,0x28,0x88,0x88 }, { 0xa0,0xa0,0xa0,0xa0 },	/* ...0...1...0...0 */
		{ 0x88,0xa0,0xa0,0x88 }, { 0x28,0x28,0x88,0x88 },	/* ...0...1...0...1 */
		{ 0xa0,0x88,0x00,0x28 }, { 0xa0,0xa0,0xa0,0xa0 },	/* ...0...1...1...0 */
		{ 0x28,0x28,0x88,0x88 }, { 0xa0,0xa0,0xa0,0xa0 },	/* ...0...1...1...1 */
		{ 0xa0,0x88,0x00,0x28 }, { 0xa0,0x88,0x00,0x28 },	/* ...1...0...0...0 */
		{ 0xa0,0x28,0xa0,0x28 }, { 0x88,0xa0,0xa0,0x88 },	/* ...1...0...0...1 */
		{ 0xa0,0x28,0xa0,0x28 }, { 0xa0,0x28,0xa0,0x28 },	/* ...1...0...1...0 */
		{ 0xa0,0x28,0xa0,0x28 }, { 0xa0,0x28,0xa0,0x28 },	/* ...1...0...1...1 */
		{ 0xa0,0x88,0x00,0x28 }, { 0xa0,0x88,0x00,0x28 },	/* ...1...1...0...0 */
		{ 0x88,0xa0,0xa0,0x88 }, { 0x28,0x28,0x88,0x88 },	/* ...1...1...0...1 */
		{ 0xa0,0xa0,0xa0,0xa0 }, { 0xa0,0x88,0x00,0x28 },	/* ...1...1...1...0 */
		{ 0x28,0x28,0x88,0x88 }, { 0xa0,0xa0,0xa0,0xa0 }	/* ...1...1...1...1 */
	};


	sega_decode(xortable);
}


void flicky_decode(void)
{
	static const unsigned char xortable[32][4] =
	{
		/*       opcode                   data                     address      */
		/*  A    B    C    D         A    B    C    D                           */
		{ 0x08,0x80,0x20,0xa8 }, { 0xa0,0x88,0x88,0xa0 },	/* ...0...0...0...0 */
		{ 0x80,0x08,0x80,0x08 }, { 0x88,0x88,0x28,0x28 },	/* ...0...0...0...1 */
		{ 0xa0,0x88,0x88,0xa0 }, { 0x28,0x00,0x00,0x28 },	/* ...0...0...1...0 */
		{ 0x28,0x00,0x00,0x28 }, { 0xa0,0x88,0x88,0xa0 },	/* ...0...0...1...1 */
		{ 0x08,0x80,0x20,0xa8 }, { 0x80,0x08,0x80,0x08 },	/* ...0...1...0...0 */
		{ 0x80,0x08,0x80,0x08 }, { 0x88,0x88,0x28,0x28 },	/* ...0...1...0...1 */
		{ 0x28,0x00,0x00,0x28 }, { 0x28,0x00,0x00,0x28 },	/* ...0...1...1...0 */
		{ 0x28,0x00,0x00,0x28 }, { 0x88,0x88,0x28,0x28 },	/* ...0...1...1...1 */
		{ 0x08,0x80,0x20,0xa8 }, { 0xa8,0x80,0x08,0x20 },	/* ...1...0...0...0 */
		{ 0xa8,0x80,0x08,0x20 }, { 0x80,0x08,0x80,0x08 },	/* ...1...0...0...1 */
		{ 0x28,0x00,0x00,0x28 }, { 0x88,0x88,0x28,0x28 },	/* ...1...0...1...0 */
		{ 0xa8,0x80,0x08,0x20 }, { 0x88,0x88,0x28,0x28 },	/* ...1...0...1...1 */
		{ 0x08,0x80,0x20,0xa8 }, { 0x80,0x08,0x80,0x08 },	/* ...1...1...0...0 */
		{ 0xa8,0x80,0x08,0x20 }, { 0x80,0x08,0x80,0x08 },	/* ...1...1...0...1 */
		{ 0x28,0x00,0x00,0x28 }, { 0x28,0x00,0x00,0x28 },	/* ...1...1...1...0 */
		{ 0x08,0x80,0x20,0xa8 }, { 0x88,0x88,0x28,0x28 }	/* ...1...1...1...1 */
	};


	sega_decode(xortable);
}


void futspy_decode(void)
{
	static const unsigned char xortable[32][4] =
	{
		/*       opcode                   data                     address      */
		/*  A    B    C    D         A    B    C    D                           */
		{ 0x28,0x00,0x00,0x28 }, { 0x28,0x00,0x00,0x28 },	/* ...0...0...0...0 */
		{ 0x80,0x08,0x80,0x08 }, { 0x08,0x80,0x20,0xa8 },	/* ...0...0...0...1 */
		{ 0x80,0x08,0x80,0x08 }, { 0x08,0x80,0x20,0xa8 },	/* ...0...0...1...0 */
		{ 0xa0,0x88,0x00,0x28 }, { 0x20,0x20,0x80,0x80 },	/* ...0...0...1...1 */
		{ 0x28,0x00,0x00,0x28 }, { 0x88,0x88,0x88,0x88 },	/* ...0...1...0...0 */
		{ 0x80,0x08,0x80,0x08 }, { 0x08,0x80,0x20,0xa8 },	/* ...0...1...0...1 */
		{ 0x80,0x08,0x80,0x08 }, { 0x20,0x20,0x80,0x80 },	/* ...0...1...1...0 */
		{ 0x20,0x20,0x80,0x80 }, { 0x08,0x80,0x20,0xa8 },	/* ...0...1...1...1 */
		{ 0x88,0x88,0x88,0x88 }, { 0x28,0x00,0x00,0x28 },	/* ...1...0...0...0 */
		{ 0x80,0x08,0x80,0x08 }, { 0xa0,0x88,0x00,0x28 },	/* ...1...0...0...1 */
		{ 0x20,0x20,0x80,0x80 }, { 0x08,0x80,0x20,0xa8 },	/* ...1...0...1...0 */
		{ 0x80,0x08,0x80,0x08 }, { 0x20,0x20,0x80,0x80 },	/* ...1...0...1...1 */
		{ 0x88,0x88,0x88,0x88 }, { 0x88,0x88,0x88,0x88 },	/* ...1...1...0...0 */
		{ 0x80,0x08,0x80,0x08 }, { 0x08,0x80,0x20,0xa8 },	/* ...1...1...0...1 */
		{ 0x80,0x08,0x80,0x08 }, { 0x28,0x00,0x00,0x28 },	/* ...1...1...1...0 */
		{ 0x20,0x20,0x80,0x80 }, { 0xa0,0x88,0x00,0x28 }	/* ...1...1...1...1 */
	};


	sega_decode(xortable);
}


void bullfgtj_decode(void)
{
	static const unsigned char xortable[32][4] =
	{
		/*       opcode                   data                     address      */
		/*  A    B    C    D         A    B    C    D                           */
		{ 0xa0,0xa0,0x00,0x00 }, { 0x80,0xa8,0x20,0x08 },	/* ...0...0...0...0 */
		{ 0x20,0x20,0x20,0x20 }, { 0x20,0x20,0x20,0x20 },	/* ...0...0...0...1 */
		{ 0xa0,0xa0,0x00,0x00 }, { 0x08,0x20,0x20,0x08 },	/* ...0...0...1...0 */
		{ 0x88,0x00,0x88,0x00 }, { 0x88,0x00,0x88,0x00 },	/* ...0...0...1...1 */
		{ 0xa0,0xa0,0x00,0x00 }, { 0x20,0x20,0x20,0x20 },	/* ...0...1...0...0 */
		{ 0x28,0xa0,0x00,0x88 }, { 0x20,0x20,0x20,0x20 },	/* ...0...1...0...1 */
		{ 0xa0,0xa0,0x00,0x00 }, { 0x08,0x20,0x20,0x08 },	/* ...0...1...1...0 */
		{ 0x88,0x00,0x88,0x00 }, { 0x88,0x00,0x88,0x00 },	/* ...0...1...1...1 */
		{ 0x28,0xa0,0x00,0x88 }, { 0xa0,0xa0,0x00,0x00 },	/* ...1...0...0...0 */
		{ 0x88,0x00,0x88,0x00 }, { 0x80,0xa8,0x20,0x08 },	/* ...1...0...0...1 */
		{ 0x28,0xa0,0x00,0x88 }, { 0x08,0x20,0x20,0x08 },	/* ...1...0...1...0 */
		{ 0x28,0xa0,0x00,0x88 }, { 0x80,0xa8,0x20,0x08 },	/* ...1...0...1...1 */
		{ 0x20,0x20,0x20,0x20 }, { 0x20,0x20,0x20,0x20 },	/* ...1...1...0...0 */
		{ 0x88,0x00,0x88,0x00 }, { 0x20,0x20,0x20,0x20 },	/* ...1...1...0...1 */
		{ 0x08,0x20,0x20,0x08 }, { 0x80,0xa8,0x20,0x08 },	/* ...1...1...1...0 */
		{ 0x08,0x20,0x20,0x08 }, { 0x88,0x00,0x88,0x00 }	/* ...1...1...1...1 */
	};


	sega_decode(xortable);
}


void pitfall2_decode(void)
{
	static const unsigned char xortable[32][4] =
	{
		/*       opcode                   data                     address      */
		/*  A    B    C    D         A    B    C    D                           */
		{ 0xa0,0x88,0x88,0xa0 }, { 0xa0,0x88,0x88,0xa0 },	/* ...0...0...0...0 */
		{ 0x08,0x80,0x08,0x80 }, { 0x28,0xa0,0x00,0x88 },	/* ...0...0...0...1 */
		{ 0xa0,0x88,0x88,0xa0 }, { 0xa0,0x88,0x88,0xa0 },	/* ...0...0...1...0 */
		{ 0xa0,0xa0,0x00,0x00 }, { 0xa0,0xa0,0x00,0x00 },	/* ...0...0...1...1 */
		{ 0xa0,0x88,0x88,0xa0 }, { 0x20,0x08,0x80,0xa8 },	/* ...0...1...0...0 */
		{ 0x28,0xa0,0x00,0x88 }, { 0x20,0x08,0x80,0xa8 },	/* ...0...1...0...1 */
		{ 0xa0,0xa0,0x00,0x00 }, { 0xa0,0xa0,0x00,0x00 },	/* ...0...1...1...0 */
		{ 0x28,0xa0,0x00,0x88 }, { 0xa0,0xa0,0x00,0x00 },	/* ...0...1...1...1 */
		{ 0x20,0x08,0x80,0xa8 }, { 0x80,0x80,0x80,0x80 },	/* ...1...0...0...0 */
		{ 0x80,0x80,0x80,0x80 }, { 0x80,0x80,0x80,0x80 },	/* ...1...0...0...1 */
		{ 0xa0,0xa0,0x00,0x00 }, { 0xa0,0x88,0x88,0xa0 },	/* ...1...0...1...0 */
		{ 0x80,0x80,0x80,0x80 }, { 0x28,0xa0,0x00,0x88 },	/* ...1...0...1...1 */
		{ 0x20,0x08,0x80,0xa8 }, { 0x80,0x80,0x80,0x80 },	/* ...1...1...0...0 */
		{ 0x80,0x80,0x80,0x80 }, { 0x20,0x08,0x80,0xa8 },	/* ...1...1...0...1 */
		{ 0xa0,0xa0,0x00,0x00 }, { 0xa0,0x88,0x88,0xa0 },	/* ...1...1...1...0 */
		{ 0x80,0x80,0x80,0x80 }, { 0x28,0xa0,0x00,0x88 }	/* ...1...1...1...1 */
	};


	sega_decode(xortable);
}


void nprinces_decode(void)
{
	static const unsigned char xortable[32][4] =
	{
		/*       opcode                   data                     address      */
		/*  A    B    C    D         A    B    C    D                           */
		{ 0x08,0x80,0x20,0xa8 }, { 0xa0,0x28,0xa0,0x28 },	/* ...0...0...0...0 */
		{ 0xa8,0xa8,0x08,0x08 }, { 0x88,0xa0,0xa0,0x88 },	/* ...0...0...0...1 */
		{ 0x88,0x88,0x28,0x28 }, { 0x28,0x00,0x88,0xa0 },	/* ...0...0...1...0 */
		{ 0x88,0xa0,0xa0,0x88 }, { 0x28,0x00,0x88,0xa0 },	/* ...0...0...1...1 */
		{ 0x88,0xa0,0xa0,0x88 }, { 0xa0,0x28,0xa0,0x28 },	/* ...0...1...0...0 */
		{ 0xa8,0xa8,0x08,0x08 }, { 0xa8,0xa8,0x08,0x08 },	/* ...0...1...0...1 */
		{ 0x88,0x88,0x28,0x28 }, { 0x88,0xa0,0xa0,0x88 },	/* ...0...1...1...0 */
		{ 0x88,0xa0,0xa0,0x88 }, { 0x88,0xa0,0xa0,0x88 },	/* ...0...1...1...1 */
		{ 0xa0,0x28,0xa0,0x28 }, { 0xa0,0x28,0xa0,0x28 },	/* ...1...0...0...0 */
		{ 0x08,0x80,0x20,0xa8 }, { 0x28,0x00,0x88,0xa0 },	/* ...1...0...0...1 */
		{ 0x88,0xa0,0xa0,0x88 }, { 0x88,0x88,0x28,0x28 },	/* ...1...0...1...0 */
		{ 0x88,0xa0,0xa0,0x88 }, { 0x28,0x00,0x88,0xa0 },	/* ...1...0...1...1 */
		{ 0x88,0xa0,0xa0,0x88 }, { 0x88,0xa0,0xa0,0x88 },	/* ...1...1...0...0 */
		{ 0x88,0xa0,0xa0,0x88 }, { 0x88,0xa0,0xa0,0x88 },	/* ...1...1...0...1 */
		{ 0x88,0x88,0x28,0x28 }, { 0x88,0x88,0x28,0x28 },	/* ...1...1...1...0 */
		{ 0x08,0x80,0x20,0xa8 }, { 0x28,0x00,0x88,0xa0 }	/* ...1...1...1...1 */
	};


	sega_decode(xortable);
}


void seganinj_decode(void)
{
	static const unsigned char xortable[32][4] =
	{
		/*       opcode                   data                     address      */
		/*  A    B    C    D         A    B    C    D                           */
		{ 0x88,0xa0,0xa0,0x88 }, { 0x88,0x00,0xa0,0x28 },	/* ...0...0...0...0 */
		{ 0x28,0xa0,0x28,0xa0 }, { 0xa0,0xa0,0xa0,0xa0 },	/* ...0...0...0...1 */
		{ 0xa8,0xa8,0x08,0x08 }, { 0xa8,0xa8,0x08,0x08 },	/* ...0...0...1...0 */
		{ 0x28,0xa0,0x28,0xa0 }, { 0xa0,0xa0,0xa0,0xa0 },	/* ...0...0...1...1 */
		{ 0x28,0x00,0x88,0xa0 }, { 0x28,0x00,0x88,0xa0 },	/* ...0...1...0...0 */
		{ 0x28,0xa0,0x28,0xa0 }, { 0x88,0x00,0xa0,0x28 },	/* ...0...1...0...1 */
		{ 0x28,0x00,0x88,0xa0 }, { 0x28,0x00,0x88,0xa0 },	/* ...0...1...1...0 */
		{ 0x28,0xa0,0x28,0xa0 }, { 0xa8,0xa8,0x08,0x08 },	/* ...0...1...1...1 */
		{ 0x88,0x00,0xa0,0x28 }, { 0x88,0xa0,0xa0,0x88 },	/* ...1...0...0...0 */
		{ 0xa0,0xa0,0xa0,0xa0 }, { 0x28,0xa0,0x28,0xa0 },	/* ...1...0...0...1 */
		{ 0xa8,0xa8,0x08,0x08 }, { 0x88,0xa0,0xa0,0x88 },	/* ...1...0...1...0 */
		{ 0xa8,0xa8,0x08,0x08 }, { 0x28,0xa0,0x28,0xa0 },	/* ...1...0...1...1 */
		{ 0x28,0x00,0x88,0xa0 }, { 0x88,0xa0,0xa0,0x88 },	/* ...1...1...0...0 */
		{ 0x28,0x00,0x88,0xa0 }, { 0x28,0x00,0x88,0xa0 },	/* ...1...1...0...1 */
		{ 0x88,0xa0,0xa0,0x88 }, { 0x88,0xa0,0xa0,0x88 },	/* ...1...1...1...0 */
		{ 0xa8,0xa8,0x08,0x08 }, { 0x28,0x00,0x88,0xa0 }	/* ...1...1...1...1 */
	};


	sega_decode(xortable);
}


void imsorry_decode(void)
{
	static const unsigned char xortable[32][4] =
	{
		/*       opcode                   data                     address      */
		/*  A    B    C    D         A    B    C    D                           */
		{ 0x88,0x00,0xa0,0x28 }, { 0x00,0x28,0xa0,0x88 },	/* ...0...0...0...0 */
		{ 0x00,0x28,0xa0,0x88 }, { 0x88,0x00,0xa0,0x28 },	/* ...0...0...0...1 */
		{ 0x88,0x00,0x88,0x00 }, { 0x00,0x28,0xa0,0x88 },	/* ...0...0...1...0 */
		{ 0x00,0x28,0xa0,0x88 }, { 0x88,0x00,0x88,0x00 },	/* ...0...0...1...1 */
		{ 0x00,0x28,0xa0,0x88 }, { 0x08,0x08,0xa8,0xa8 },	/* ...0...1...0...0 */
		{ 0x00,0x28,0xa0,0x88 }, { 0x20,0x20,0x80,0x80 },	/* ...0...1...0...1 */
		{ 0x20,0x20,0x80,0x80 }, { 0x00,0x28,0xa0,0x88 },	/* ...0...1...1...0 */
		{ 0x20,0x20,0x80,0x80 }, { 0x88,0x00,0x88,0x00 },	/* ...0...1...1...1 */
		{ 0x88,0x00,0xa0,0x28 }, { 0x08,0x08,0xa8,0xa8 },	/* ...1...0...0...0 */
		{ 0x08,0x08,0xa8,0xa8 }, { 0x88,0x00,0xa0,0x28 },	/* ...1...0...0...1 */
		{ 0x08,0x20,0x20,0x08 }, { 0x08,0x20,0x20,0x08 },	/* ...1...0...1...0 */
		{ 0x88,0x00,0xa0,0x28 }, { 0x08,0x20,0x20,0x08 },	/* ...1...0...1...1 */
		{ 0x08,0x20,0x20,0x08 }, { 0x08,0x08,0xa8,0xa8 },	/* ...1...1...0...0 */
		{ 0x08,0x20,0x20,0x08 }, { 0x20,0x20,0x80,0x80 },	/* ...1...1...0...1 */
		{ 0x20,0x20,0x80,0x80 }, { 0x08,0x20,0x20,0x08 },	/* ...1...1...1...0 */
		{ 0x20,0x20,0x80,0x80 }, { 0x08,0x20,0x20,0x08 }	/* ...1...1...1...1 */
	};


	sega_decode(xortable);
}


void teddybb_decode(void)
{
	static const unsigned char xortable[32][4] =
	{
		/*       opcode                   data                     address      */
		/*  A    B    C    D         A    B    C    D                           */
		{ 0x20,0x20,0x20,0x20 }, { 0x80,0x08,0x80,0x08 },	/* ...0...0...0...0 */
		{ 0x20,0x20,0x20,0x20 }, { 0xa0,0xa0,0x00,0x00 },	/* ...0...0...0...1 */
		{ 0x28,0x00,0x88,0xa0 }, { 0xa0,0x88,0x88,0xa0 },	/* ...0...0...1...0 */
		{ 0xa0,0xa0,0x00,0x00 }, { 0xa0,0x88,0x88,0xa0 },	/* ...0...0...1...1 */
		{ 0x20,0x20,0x20,0x20 }, { 0x28,0x00,0x88,0xa0 },	/* ...0...1...0...0 */
		{ 0xa0,0xa0,0x00,0x00 }, { 0xa0,0xa0,0x00,0x00 },	/* ...0...1...0...1 */
		{ 0xa0,0x88,0x88,0xa0 }, { 0x28,0x00,0x88,0xa0 },	/* ...0...1...1...0 */
		{ 0xa0,0xa0,0x00,0x00 }, { 0x28,0x00,0x88,0xa0 },	/* ...0...1...1...1 */
		{ 0x80,0x08,0x80,0x08 }, { 0x80,0x08,0x80,0x08 },	/* ...1...0...0...0 */
		{ 0xa0,0x28,0x88,0x00 }, { 0xa0,0xa0,0x00,0x00 },	/* ...1...0...0...1 */
		{ 0xa0,0x28,0x88,0x00 }, { 0xa0,0x88,0x88,0xa0 },	/* ...1...0...1...0 */
		{ 0xa0,0x88,0x88,0xa0 }, { 0xa0,0x88,0x88,0xa0 },	/* ...1...0...1...1 */
		{ 0x80,0x08,0x80,0x08 }, { 0x20,0x20,0x20,0x20 },	/* ...1...1...0...0 */
		{ 0xa0,0xa0,0x00,0x00 }, { 0xa0,0x28,0x88,0x00 },	/* ...1...1...0...1 */
		{ 0x80,0x08,0x80,0x08 }, { 0xa0,0x88,0x88,0xa0 },	/* ...1...1...1...0 */
		{ 0xa0,0xa0,0x00,0x00 }, { 0xa0,0x28,0x88,0x00 }	/* ...1...1...1...1 */
	};


	sega_decode(xortable);
}


void hvymetal_decode(void)
{
	static const unsigned char xortable[32][4] =
	{
		/*       opcode                   data                     address      */
		/*  A    B    C    D         A    B    C    D                           */
		{ 0x88,0xa0,0xa0,0x88 }, { 0xa0,0x88,0x88,0xa0 },	/* ...0...0...0...0 */
		{ 0x88,0xa0,0xa0,0x88 }, { 0x88,0x88,0x28,0x28 },	/* ...0...0...0...1 */
		{ 0xa0,0x88,0x88,0xa0 }, { 0x88,0xa0,0xa0,0x88 },	/* ...0...0...1...0 */
		{ 0x88,0xa0,0xa0,0x88 }, { 0x88,0x88,0x28,0x28 },	/* ...0...0...1...1 */
		{ 0xa0,0x88,0x88,0xa0 }, { 0x88,0x88,0x28,0x28 },	/* ...0...1...0...0 */
		{ 0x88,0x88,0x28,0x28 }, { 0x88,0x88,0x28,0x28 },	/* ...0...1...0...1 */
		{ 0xa0,0x88,0x88,0xa0 }, { 0x88,0x88,0x28,0x28 },	/* ...0...1...1...0 */
		{ 0x88,0x88,0x28,0x28 }, { 0x28,0x00,0x88,0xa0 },	/* ...0...1...1...1 */
		{ 0xa0,0x28,0x88,0x00 }, { 0x88,0xa0,0xa0,0x88 },	/* ...1...0...0...0 */
		{ 0xa0,0x28,0x88,0x00 }, { 0x88,0xa0,0xa0,0x88 },	/* ...1...0...0...1 */
		{ 0xa0,0x28,0x88,0x00 }, { 0x88,0xa0,0xa0,0x88 },	/* ...1...0...1...0 */
		{ 0x88,0xa0,0xa0,0x88 }, { 0x28,0x00,0x88,0xa0 },	/* ...1...0...1...1 */
		{ 0x28,0xa0,0x28,0xa0 }, { 0xa0,0x28,0x88,0x00 },	/* ...1...1...0...0 */
		{ 0xa0,0x28,0x88,0x00 }, { 0x28,0xa0,0x28,0xa0 },	/* ...1...1...0...1 */
		{ 0x28,0xa0,0x28,0xa0 }, { 0xa0,0x28,0x88,0x00 },	/* ...1...1...1...0 */
		{ 0x28,0x00,0x88,0xa0 }, { 0x28,0xa0,0x28,0xa0 }	/* ...1...1...1...1 */
	};


	sega_decode(xortable);
}


void myheroj_decode(void)
{
	static const unsigned char xortable[32][4] =
	{
		/*       opcode                   data                     address      */
		/*  A    B    C    D         A    B    C    D                           */
		{ 0x20,0x08,0x80,0xa8 }, { 0x80,0xa8,0xa8,0x80 },	/* ...0...0...0...0 */
		{ 0x20,0x08,0x80,0xa8 }, { 0x80,0xa8,0xa8,0x80 },	/* ...0...0...0...1 */
		{ 0xa8,0xa8,0xa8,0xa8 }, { 0xa8,0xa8,0xa8,0xa8 },	/* ...0...0...1...0 */
		{ 0x08,0x80,0x20,0xa8 }, { 0x80,0xa8,0xa8,0x80 },	/* ...0...0...1...1 */
		{ 0x20,0x08,0x80,0xa8 }, { 0x28,0xa0,0x28,0xa0 },	/* ...0...1...0...0 */
		{ 0x20,0x08,0x80,0xa8 }, { 0x08,0x80,0x20,0xa8 },	/* ...0...1...0...1 */
		{ 0x28,0xa0,0x28,0xa0 }, { 0xa8,0xa8,0xa8,0xa8 },	/* ...0...1...1...0 */
		{ 0x08,0x80,0x20,0xa8 }, { 0xa8,0xa8,0xa8,0xa8 },	/* ...0...1...1...1 */
		{ 0x28,0xa0,0x28,0xa0 }, { 0x20,0x08,0x80,0xa8 },	/* ...1...0...0...0 */
		{ 0x80,0xa8,0xa8,0x80 }, { 0x20,0x08,0x80,0xa8 },	/* ...1...0...0...1 */
		{ 0x80,0xa8,0xa8,0x80 }, { 0x80,0xa8,0xa8,0x80 },	/* ...1...0...1...0 */
		{ 0xa8,0xa8,0xa8,0xa8 }, { 0x80,0xa8,0xa8,0x80 },	/* ...1...0...1...1 */
		{ 0x88,0x88,0x28,0x28 }, { 0x88,0x88,0x28,0x28 },	/* ...1...1...0...0 */
		{ 0x88,0x88,0x28,0x28 }, { 0x08,0x80,0x20,0xa8 },	/* ...1...1...0...1 */
		{ 0x88,0x88,0x28,0x28 }, { 0xa8,0xa8,0xa8,0xa8 },	/* ...1...1...1...0 */
		{ 0x88,0x88,0x28,0x28 }, { 0xa8,0xa8,0xa8,0xa8 }	/* ...1...1...1...1 */
	};


	sega_decode(xortable);
}


/******************************************************************************

  4D Warriors

  This encryption is quite different from the standard one. It is still
  a XOR scheme, but the value to use for the XOR is chosen differently, and
  the affected bits are D0, D2, D4 and D6 instead of D3, D5 and D7.

  The translation table depends on A0, A3, A6, A9, A12 and A14; however A0, A3
  and A6 only select some fixed additional XOR, so there are only 8 really
  different tables.

  There are no separate tables for data and opcodes: the opcodes are just XORed
  with an additional 0x40. To make it a little more complicated, however, data
  picks its XOR value not from the line given by the address but from the one
  below. For example if you are decoding a byte at address .1.0..1..0..1..0,
  you pick the XOR value as if you were at address .1.0..1..0..1..1 (note that
  I'm not talking about the rows of the xortable below, but of the "logical"
  ones which are generated by them with the additional fixed XORs selected by
  A0, A3 and A6).

******************************************************************************/

void fdwarrio_decode(void)
{
	static const unsigned char xortable[8+1][8] =
	{
		/* note how the first lines are highly repetitive, while the */
		/* last ones get more and more unique. */
		{ 0x00,0x00,0x14,0x14,0x14,0x14,0x00,0x00 },	/* .0.0..0..x..x..x */
		{ 0x00,0x11,0x00,0x11,0x11,0x00,0x11,0x00 },	/* .0.0..1..x..x..x */
		{ 0x00,0x05,0x05,0x00,0x00,0x05,0x05,0x00 },	/* .0.1..0..x..x..x */
		{ 0x00,0x00,0x44,0x44,0x14,0x14,0x50,0x50 },	/* .0.1..1..x..x..x */
		{ 0x00,0x00,0x14,0x14,0x50,0x50,0x44,0x44 },	/* .1.0..0..x..x..x */
		{ 0x00,0x05,0x05,0x00,0x50,0x55,0x55,0x50 },	/* .1.0..1..x..x..x */
		{ 0x00,0x11,0x05,0x14,0x14,0x05,0x11,0x00 },	/* .1.1..0..x..x..x */
		{ 0x00,0x41,0x05,0x44,0x14,0x55,0x11,0x50 },	/* .1.1..1..x..x..x */
		{ 0x00,0x11,0x05,0x14,0x50,0x41,0x55,0x44 }		/* extra line for data decode */
	};
	int A;
	unsigned char *rom = memory_region(REGION_CPU1);
	int diff = memory_region_length(REGION_CPU1) / 2;


	memory_set_opcode_base(0,rom+diff);

	for (A = 0x0000;A < 0x8000;A++)
	{
		int row,col;
		unsigned char src;


		src = rom[A];

		/* pick the translation table from bits 0, 3, 6, 9, 12 and 14 of the address */
		row = (A & 1) + (((A >> 3) & 1) << 1) + (((A >> 6) & 1) << 2)
				+ (((A >> 9) & 1) << 3) + (((A >> 12) & 1) << 4) + (((A >> 14) & 1) << 5);

		/* pick the offset in the table from bits 0, 2, 4 and 6 of the source data */
		col = ((src >> 0) & 1) + (((src >> 2) & 1) << 1) + (((src >> 4) & 1) << 2);
		/* the bottom half of the translation table is the mirror image of the top */
		if (src & 0x40) col = 7 - col;

		/* decode the opcodes */
		rom[A + diff] = src ^ xortable[row >> 3][col] ^ 0x40;
		if (row & 1) rom[A + diff] ^= 0x10;
		if (row & 2) rom[A + diff] ^= 0x04;
		if (row & 4) rom[A + diff] ^= 0x01;

		/* decode the data */
		row++;	/* the data XOR table is shifted by one position!!!! */
		rom[A] = src ^ xortable[row >> 3][col];
		if (row & 1) rom[A] ^= 0x10;
		if (row & 2) rom[A] ^= 0x04;
		if (row & 4) rom[A] ^= 0x01;
	}

	/* copy the opcodes from the not encrypted part of the ROMs */
	for (A = 0x8000;A < diff;A++)
		rom[A + diff] = rom[A];
}



/******************************************************************************

  Wonder Boy

  This is different again. It is similar to 4D Warriors - it affects the same
  data bits and is selected by the same address lines, but I haven't been able
  to find any regularities in the XOR table, so I'm using a huge 1024 bytes
  array.

******************************************************************************/

void wboy3_decode(void)
{
	/* not decoded yet! */
}


void wboy4_decode(void)
{
	static const unsigned char opcode_xortable[8*8][8] =
	{
		{ 0x00,0x00,0x44,0x44,0x00,0x00,0x44,0x44 },	/* .0.0 ..0. .0.. 0..0 */
		{ 0x45,0x54,0x45,0x54,0x54,0x45,0x54,0x45 },	/* .0.0 ..0. .0.. 0..1 */
		{ 0x11,0x11,0x11,0x11,0x41,0x41,0x41,0x41 },	/* .0.0 ..0. .0.. 1..0 */
		{ 0x01,0x10,0x01,0x10,0x10,0x01,0x10,0x01 },	/* .0.0 ..0. .0.. 1..1 */
		{ 0x44,0x44,0x44,0x44,0x14,0x14,0x14,0x14 },	/* .0.0 ..0. .1.. 0..0 */
		{ 0x10,0x01,0x10,0x01,0x01,0x10,0x01,0x10 },	/* .0.0 ..0. .1.. 0..1 */
		{ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55 },	/* .0.0 ..0. .1.. 1..0 */
		{ 0x05,0x05,0x11,0x11,0x11,0x11,0x05,0x05 },	/* .0.0 ..0. .1.. 1..1 */
		{ 0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41 },	/* .0.0 ..1. .0.. 0..0 */
		{ 0x14,0x14,0x00,0x00,0x00,0x00,0x14,0x14 },	/* .0.0 ..1. .0.. 0..1 */
		{ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04 },	/* .0.0 ..1. .0.. 1..0 */
		{ 0x40,0x40,0x54,0x54,0x54,0x54,0x40,0x40 },	/* .0.0 ..1. .0.. 1..1 */
		{ 0x15,0x15,0x51,0x51,0x01,0x01,0x45,0x45 },	/* .0.0 ..1. .1.. 0..0 */
		{ 0x51,0x10,0x51,0x10,0x51,0x10,0x51,0x10 },	/* .0.0 ..1. .1.. 0..1 */
		{ 0x01,0x01,0x45,0x45,0x15,0x15,0x51,0x51 },	/* .0.0 ..1. .1.. 1..0 */
		{ 0x44,0x05,0x44,0x05,0x44,0x05,0x44,0x05 },	/* .0.0 ..1. .1.. 1..1 */
		{ 0x10,0x10,0x54,0x54,0x04,0x04,0x40,0x40 },	/* .0.1 ..0. .0.. 0..0 */
		{ 0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41 },	/* .0.1 ..0. .0.. 0..1 */
		{ 0x45,0x40,0x40,0x45,0x45,0x40,0x40,0x45 },	/* .0.1 ..0. .0.. 1..0 */
		{ 0x11,0x11,0x55,0x55,0x11,0x11,0x55,0x55 },	/* .0.1 ..0. .0.. 1..1 */
		{ 0x54,0x51,0x51,0x54,0x54,0x51,0x51,0x54 },	/* .0.1 ..0. .1.. 0..0 */
		{ 0x04,0x04,0x40,0x40,0x04,0x04,0x40,0x40 },	/* .0.1 ..0. .1.. 0..1 */
		{ 0x40,0x45,0x45,0x40,0x40,0x45,0x45,0x40 },	/* .0.1 ..0. .1.. 1..0 */
		{ 0x15,0x15,0x15,0x15,0x45,0x45,0x45,0x45 },	/* .0.1 ..0. .1.. 1..1 */
		{ 0x05,0x14,0x05,0x14,0x14,0x05,0x14,0x05 },	/* .0.1 ..1. .0.. 0..0 */
		{ 0x41,0x41,0x41,0x41,0x11,0x11,0x11,0x11 },	/* .0.1 ..1. .0.. 0..1 */
		{ 0x14,0x05,0x14,0x05,0x05,0x14,0x05,0x14 },	/* .0.1 ..1. .0.. 1..0 */
		{ 0x50,0x50,0x50,0x50,0x00,0x00,0x00,0x00 },	/* .0.1 ..1. .0.. 1..1 */
		{ 0x00,0x11,0x00,0x11,0x11,0x00,0x11,0x00 },	/* .0.1 ..1. .1.. 0..0 */
		{ 0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45 },	/* .0.1 ..1. .1.. 0..1 */
		{ 0x11,0x11,0x05,0x05,0x05,0x05,0x11,0x11 },	/* .0.1 ..1. .1.. 1..0 */
		{ 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01 },	/* .0.1 ..1. .1.. 1..1 */
		{ 0x00,0x11,0x05,0x14,0x14,0x05,0x11,0x00 },	/* .1.0 ..0. .0.. 0..0 */
		{ 0x45,0x04,0x40,0x01,0x45,0x04,0x40,0x01 },	/* .1.0 ..0. .0.. 0..1 */
		{ 0x11,0x14,0x14,0x11,0x41,0x44,0x44,0x41 },	/* .1.0 ..0. .0.. 1..0 */
		{ 0x01,0x40,0x04,0x45,0x01,0x40,0x04,0x45 },	/* .1.0 ..0. .0.. 1..1 */
		{ 0x44,0x41,0x41,0x44,0x14,0x11,0x11,0x14 },	/* .1.0 ..0. .1.. 0..0 */
		{ 0x10,0x51,0x15,0x54,0x10,0x51,0x15,0x54 },	/* .1.0 ..0. .1.. 0..1 */
		{ 0x55,0x55,0x41,0x41,0x05,0x05,0x11,0x11 },	/* .1.0 ..0. .1.. 1..0 */
		{ 0x05,0x14,0x00,0x11,0x55,0x44,0x50,0x41 },	/* .1.0 ..0. .1.. 1..1 */
		{ 0x41,0x41,0x55,0x55,0x11,0x11,0x05,0x05 },	/* .1.0 ..1. .0.. 0..0 */
		{ 0x14,0x05,0x11,0x00,0x44,0x55,0x41,0x50 },	/* .1.0 ..1. .0.. 0..1 */
		{ 0x04,0x04,0x10,0x10,0x54,0x54,0x40,0x40 },	/* .1.0 ..1. .0.. 1..0 */
		{ 0x40,0x51,0x45,0x54,0x10,0x01,0x15,0x04 },	/* .1.0 ..1. .0.. 1..1 */
		{ 0x15,0x10,0x51,0x54,0x04,0x01,0x40,0x45 },	/* .1.0 ..1. .1.. 0..0 */
		{ 0x51,0x10,0x54,0x15,0x45,0x04,0x40,0x01 },	/* .1.0 ..1. .1.. 0..1 */
		{ 0x01,0x04,0x45,0x40,0x10,0x15,0x54,0x51 },	/* .1.0 ..1. .1.. 1..0 */
		{ 0x44,0x05,0x41,0x00,0x50,0x11,0x55,0x14 },	/* .1.0 ..1. .1.. 1..1 */
		/* the following are all FF because there is no code to decode */
		{ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff },	/* .1.1 ..0. .0.. 0..0 */
		{ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff },	/* .1.1 ..0. .0.. 0..1 */
		{ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff },	/* .1.1 ..0. .0.. 1..0 */
		{ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff },	/* .1.1 ..0. .0.. 1..1 */
		{ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff },	/* .1.1 ..0. .1.. 0..0 */
		{ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff },	/* .1.1 ..0. .1.. 0..1 */
		{ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff },	/* .1.1 ..0. .1.. 1..0 */
		{ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff },	/* .1.1 ..0. .1.. 1..1 */
		{ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff },	/* .1.1 ..1. .0.. 0..0 */
		{ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff },	/* .1.1 ..1. .0.. 0..1 */
		{ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff },	/* .1.1 ..1. .0.. 1..0 */
		{ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff },	/* .1.1 ..1. .0.. 1..1 */
		{ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff },	/* .1.1 ..1. .1.. 0..0 */
		{ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff },	/* .1.1 ..1. .1.. 0..1 */
		{ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff },	/* .1.1 ..1. .1.. 1..0 */
		{ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff },	/* .1.1 ..1. .1.. 1..1 */
	};
	static const unsigned char data_xortable[8*8][8] =
	{
		{ 0x55,0x14,0x55,0x14,0x55,0x14,0x55,0x14 },	/* .0.0 ..0. .0.. 0..0 */
		{ 0x05,0x05,0x41,0x41,0x11,0x11,0x55,0x55 },	/* .0.0 ..0. .0.. 0..1 */
		{ 0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00 },	/* .0.0 ..0. .0.. 1..0 */
		{ 0x14,0x14,0x50,0x50,0x00,0x00,0x44,0x44 },	/* .0.0 ..0. .0.. 1..1 */
		{ 0x50,0x11,0x50,0x11,0x50,0x11,0x50,0x11 },	/* .0.0 ..0. .1.. 0..0 */
		{ 0x00,0x00,0x44,0x44,0x14,0x14,0x50,0x50 },	/* .0.0 ..0. .1.. 0..1 */
		{ 0x15,0x15,0x51,0x51,0x15,0x15,0x51,0x51 },	/* .0.0 ..0. .1.. 1..0 */
		{ 0x51,0x54,0x54,0x51,0x51,0x54,0x54,0x51 },	/* .0.0 ..0. .1.. 1..1 */
		{ 0x01,0x01,0x45,0x45,0x01,0x01,0x45,0x45 },	/* .0.0 ..1. .0.. 0..0 */
		{ 0x44,0x41,0x41,0x44,0x44,0x41,0x41,0x44 },	/* .0.0 ..1. .0.. 0..1 */
		{ 0x10,0x10,0x54,0x54,0x10,0x10,0x54,0x54 },	/* .0.0 ..1. .0.. 1..0 */
		{ 0x55,0x44,0x55,0x44,0x44,0x55,0x44,0x55 },	/* .0.0 ..1. .0.. 1..1 */
		{ 0x05,0x05,0x05,0x05,0x55,0x55,0x55,0x55 },	/* .0.0 ..1. .1.. 0..0 */
		{ 0x11,0x00,0x11,0x00,0x00,0x11,0x00,0x11 },	/* .0.0 ..1. .1.. 0..1 */
		{ 0x54,0x54,0x54,0x54,0x04,0x04,0x04,0x04 },	/* .0.0 ..1. .1.. 1..0 */
		{ 0x04,0x15,0x04,0x15,0x15,0x04,0x15,0x04 },	/* .0.0 ..1. .1.. 1..1 */
		{ 0x40,0x40,0x40,0x40,0x10,0x10,0x10,0x10 },	/* .0.1 ..0. .0.. 0..0 */
		{ 0x15,0x15,0x01,0x01,0x01,0x01,0x15,0x15 },	/* .0.1 ..0. .0.. 0..1 */
		{ 0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51 },	/* .0.1 ..0. .0.. 1..0 */
		{ 0x01,0x01,0x15,0x15,0x15,0x15,0x01,0x01 },	/* .0.1 ..0. .0.. 1..1 */
		{ 0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14 },	/* .0.1 ..0. .1.. 0..0 */
		{ 0x50,0x50,0x44,0x44,0x44,0x44,0x50,0x50 },	/* .0.1 ..0. .1.. 0..1 */
		{ 0x00,0x00,0x14,0x14,0x50,0x50,0x44,0x44 },	/* .0.1 ..0. .1.. 1..0 */
		{ 0x45,0x04,0x45,0x04,0x45,0x04,0x45,0x04 },	/* .0.1 ..0. .1.. 1..1 */
		{ 0x11,0x11,0x55,0x55,0x05,0x05,0x41,0x41 },	/* .0.1 ..1. .0.. 0..0 */
		{ 0x54,0x15,0x54,0x15,0x54,0x15,0x54,0x15 },	/* .0.1 ..1. .0.. 0..1 */
		{ 0x04,0x04,0x40,0x40,0x10,0x10,0x54,0x54 },	/* .0.1 ..1. .0.. 1..0 */
		{ 0x10,0x51,0x10,0x51,0x10,0x51,0x10,0x51 },	/* .0.1 ..1. .0.. 1..1 */
		{ 0x55,0x50,0x50,0x55,0x55,0x50,0x50,0x55 },	/* .0.1 ..1. .1.. 0..0 */
		{ 0x05,0x05,0x41,0x41,0x05,0x05,0x41,0x41 },	/* .0.1 ..1. .1.. 0..1 */
		{ 0x41,0x44,0x44,0x41,0x41,0x44,0x44,0x41 },	/* .0.1 ..1. .1.. 1..0 */
		{ 0x14,0x14,0x50,0x50,0x14,0x14,0x50,0x50 },	/* .0.1 ..1. .1.. 1..1 */
		{ 0x55,0x14,0x50,0x11,0x41,0x00,0x44,0x05 },	/* .1.0 ..0. .0.. 0..0 */
		{ 0x05,0x00,0x41,0x44,0x14,0x11,0x50,0x55 },	/* .1.0 ..0. .0.. 0..1 */
		{ 0x41,0x00,0x44,0x05,0x55,0x14,0x50,0x11 },	/* .1.0 ..0. .0.. 1..0 */
		{ 0x14,0x11,0x50,0x55,0x05,0x00,0x41,0x44 },	/* .1.0 ..0. .0.. 1..1 */
		{ 0x50,0x11,0x55,0x14,0x44,0x05,0x41,0x00 },	/* .1.0 ..0. .1.. 0..0 */
		{ 0x00,0x05,0x44,0x41,0x11,0x14,0x55,0x50 },	/* .1.0 ..0. .1.. 0..1 */
		{ 0x15,0x04,0x10,0x01,0x01,0x10,0x04,0x15 },	/* .1.0 ..0. .1.. 1..0 */
		{ 0x51,0x54,0x45,0x40,0x40,0x45,0x54,0x51 },	/* .1.0 ..0. .1.. 1..1 */
		{ 0x01,0x10,0x04,0x15,0x15,0x04,0x10,0x01 },	/* .1.0 ..1. .0.. 0..0 */
		{ 0x44,0x41,0x50,0x55,0x55,0x50,0x41,0x44 },	/* .1.0 ..1. .0.. 0..1 */
		{ 0x10,0x01,0x15,0x04,0x04,0x15,0x01,0x10 },	/* .1.0 ..1. .0.. 1..0 */
		{ 0x55,0x14,0x50,0x11,0x55,0x14,0x50,0x11 },	/* .1.0 ..1. .0.. 1..1 */
		{ 0x05,0x00,0x00,0x05,0x55,0x50,0x50,0x55 },	/* .1.0 ..1. .1.. 0..0 */
		{ 0x11,0x50,0x14,0x55,0x11,0x50,0x14,0x55 },	/* .1.0 ..1. .1.. 0..1 */
		{ 0x54,0x51,0x51,0x54,0x04,0x01,0x01,0x04 },	/* .1.0 ..1. .1.. 1..0 */
		{ 0x04,0x45,0x01,0x40,0x04,0x45,0x01,0x40 },	/* .1.0 ..1. .1.. 1..1 */
		{ 0x40,0x45,0x45,0x40,0x10,0x15,0x15,0x10 },	/* .1.1 ..0. .0.. 0..0 */
		{ 0x15,0x04,0x10,0x01,0x45,0x54,0x40,0x51 },	/* .1.1 ..0. .0.. 0..1 */
		{ 0x51,0x51,0x45,0x45,0x01,0x01,0x15,0x15 },	/* .1.1 ..0. .0.. 1..0 */
		{ 0x01,0x10,0x04,0x15,0x51,0x40,0x54,0x45 },	/* .1.1 ..0. .0.. 1..1 */
		{ 0x14,0x14,0x00,0x00,0x44,0x44,0x50,0x50 },	/* .1.1 ..0. .1.. 0..0 */
		{ 0x50,0x41,0x55,0x44,0x00,0x11,0x05,0x14 },	/* .1.1 ..0. .1.. 0..1 */
		{ 0x00,0x41,0x00,0x41,0x11,0x50,0x11,0x50 },	/* .1.1 ..0. .1.. 1..0 */
		{ 0x45,0x04,0x40,0x01,0x51,0x10,0x54,0x15 },	/* .1.1 ..0. .1.. 1..1 */
		{ 0x11,0x14,0x55,0x50,0x00,0x05,0x44,0x41 },	/* .1.1 ..1. .0.. 0..0 */
		{ 0x54,0x15,0x51,0x10,0x40,0x01,0x45,0x04 },	/* .1.1 ..1. .0.. 0..1 */
		{ 0x04,0x01,0x40,0x45,0x15,0x10,0x51,0x54 },	/* .1.1 ..1. .0.. 1..0 */
		{ 0x10,0x51,0x15,0x54,0x04,0x45,0x01,0x40 },	/* .1.1 ..1. .0.. 1..1 */
		{ 0x55,0x50,0x41,0x44,0x44,0x41,0x50,0x55 },	/* .1.1 ..1. .1.. 0..0 */
		{ 0x05,0x14,0x00,0x11,0x11,0x00,0x14,0x05 },	/* .1.1 ..1. .1.. 0..1 */
		{ 0x41,0x44,0x55,0x50,0x50,0x55,0x44,0x41 },	/* .1.1 ..1. .1.. 1..0 */
		{ 0x14,0x05,0x11,0x00,0x00,0x11,0x05,0x14 },	/* .1.1 ..1. .1.. 1..1 */
	};
	int A;
	unsigned char *rom = memory_region(REGION_CPU1);
	int diff = memory_region_length(REGION_CPU1) / 2;


	memory_set_opcode_base(0,rom+diff);

	for (A = 0x0000;A < 0x8000;A++)
	{
		int row,col;
		unsigned char src;


		src = rom[A];

		/* pick the translation table from bits 0, 3, 6, 9, 12 and 14 of the address */
		row = (A & 1) + (((A >> 3) & 1) << 1) + (((A >> 6) & 1) << 2)
				+ (((A >> 9) & 1) << 3) + (((A >> 12) & 1) << 4) + (((A >> 14) & 1) << 5);

		/* pick the offset in the table from bits 0, 2, 4 and 6 of the source data */
		col = ((src >> 0) & 1) + (((src >> 2) & 1) << 1) + (((src >> 4) & 1) << 2);
		/* the bottom half of the translation table is the mirror image of the top */
		if (src & 0x40) col = 7 - col;

		/* decode the opcodes */
		rom[A + diff] = src ^ opcode_xortable[row][col] ^ 0x00;

		/* decode the data */
		rom[A] = src ^ data_xortable[row][col];
	}

	/* copy the opcodes from the not encrypted part of the ROMs */
	for (A = 0x8000;A < diff;A++)
		rom[A + diff] = rom[A];
}


void gardia_decode(void)
{
	/* not decoded yet! */
}
